package com.laxcen.basiclib;

import android.app.Application;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import com.laxcen.basiclib.bean.Config;
import com.laxcen.basiclib.core.bridgewebview.bean.PushLog;
import com.laxcen.basiclib.core.crashcatch.CrashCatchManager;
import com.laxcen.basiclib.core.crashcatch.handler.IExceptionHandler;
import com.laxcen.basiclib.core.crashpush.CrashPushManager;
import com.laxcen.basiclib.core.http.HttpManager;
import com.laxcen.basiclib.core.http.cookie.CookieJarImpl;
import com.laxcen.basiclib.core.http.cookie.store.PersistentCookieStore;
import com.laxcen.basiclib.core.http.ssl.SslUtils;
import com.laxcen.basiclib.core.http.log.LoggerInterceptor;
import com.laxcen.basiclib.core.keeplive.KeepLive;
import com.laxcen.basiclib.core.task.TaskManager;
import com.laxcen.basiclib.core.task.core.thread.ThreadPoolConfig;
import com.laxcen.basiclib.core.task.core.thread.ThreadPoolManager;
import com.laxcen.basiclib.core.update.Update;
import com.laxcen.basiclib.core.update.http.UpdateHttpService;
import com.laxcen.basiclib.core.update.utils.UpdateUtils;
import com.laxcen.basiclib.core.weex.WeexManager;
import com.laxcen.basiclib.utils.SharedPreferencesUtil;

import java.util.List;
import java.util.concurrent.TimeUnit;

import io.sentry.Sentry;
import io.sentry.SentryLevel;
import okhttp3.OkHttpClient;

import static com.laxcen.basiclib.core.update.entity.UpdateError.ERROR.CHECK_NO_NEW_VERSION;


public abstract class BaseApp extends Application implements IExceptionHandler {

    @Override
    public void onCreate() {
        super.onCreate();
        app = this;
        BaseConst.init(initConfig());
        init();
    }

    //这里设置让其他项目引用时可修改
    public abstract Config initConfig();
    //需要保活的进程
    public abstract List<Class<? extends Service>> keepService();
    //执行完之后调用
    public abstract void ready();

    /**
     *  初始化
     */
    private void init(){
        //weex初始化
        WeexManager.getInstance().init(this);

        //异步线程管理初始化
        ThreadPoolConfig config = ThreadPoolConfig
                .newBuilder("laxcen").asThreadPool();
        ThreadPoolManager.init(config);
        TaskManager.getInstance().init(50);
        SharedPreferencesUtil.getInstance(app, BaseConst.dbName);

        //http 相关配置初始化
        //cookie
        CookieJarImpl cookieJar = new CookieJarImpl(new PersistentCookieStore(getApplicationContext()));
        //ssl
        SslUtils.SSLParams sslParams = SslUtils.getSslSocketFactory(null, null, null);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                 .addInterceptor(new LoggerInterceptor(HttpManager.TAG))
                .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
                .connectTimeout(10000L, TimeUnit.MILLISECONDS)
                .readTimeout(10000L, TimeUnit.MILLISECONDS)
                .cookieJar(cookieJar)
                .build();
        HttpManager.initClient(okHttpClient);

        /**
         * 更新初始化
         */
        Update.get()
                .debug(BaseConst.DEBUG)
                //默认设置只在wifi下检查版本更新
                .isWifiOnly(false)
                //默认设置使用get请求检查版本
                .isGet(true)
                //默认设置非自动模式，可根据具体使用配置
                .isAutoMode(false)
                //设置默认公共请求参数
                .param("versionCode", UpdateUtils.getVersionCode(this))
                .param("appId", BaseConst.appId)
                //设置版本更新出错的监听
                .setOnUpdateFailureListener(error -> {
                    error.printStackTrace();
                    //对不同错误进行处理
                    if (error.getCode() != CHECK_NO_NEW_VERSION) {

                    }
                })
                //设置是否支持静默安装，默认是true
                .supportSilentInstall(false)
                //实现网络请求功能。
                .setIUpdateHttpService(new UpdateHttpService())
                //初始化
                .init(this);

        //启动保活机制
        List<Class<? extends Service>> services = keepService();
        KeepLive.initKeepLive(this,services);

        ready();
    }


    private static BaseApp app;
    public static BaseApp getApp() {
        return app;
    }


    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        CrashCatchManager.initialize(this);
        CrashCatchManager.install(this::onCaughtException,true,true,true);
    }

    /**
     *  处理全局崩溃异常
     * @param thread
     * @param throwable
     * @param isAllSollapse 完全崩溃
     * @param isBlankInterface  界面空白
     * @throws Throwable
     */
    @Override
    public void onCaughtException(Thread thread, Throwable throwable, boolean isAllSollapse,
                                  boolean isBlankInterface){
        Log.e("onCaughtException",throwable.getMessage());
        PushLog pushLog = new PushLog();
        pushLog.setType("java");
        pushLog.setLevel(SentryLevel.ERROR);
        pushLog.setThrowable(throwable);
        pushLog.setThread(thread.getName()+":"+thread.getId());
        pushLog.setAllSollapse(isAllSollapse);
        pushLog.setBlankInterface(isBlankInterface);
        CrashPushManager.getInstance().pushLog(pushLog);
    }

    /**
     * 发送崩溃广播
     * @param title
     * @param context
     */
    public void sendCaughtMessage(String title,String context){
        Log.e("sendCaughtMessage",context);
        Intent intent = new Intent();
        intent.setAction(BaseConst.CAUGHT_EXCEPTION);
        intent.putExtra("title",title);
        intent.putExtra("context",context);
        getApplicationContext().sendBroadcast(intent);
    }
}
